package server.sat;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Callable;

import server.core.Database;
import server.core.Solution;

/**
 * The SATCacheQuery class defines an object that searches a {@link Database}
 * for the key from a {@link SATProblem}, returning a {@link SATSolution} if it
 * finds one for the given problem.
 * 
 * @author Clayton Edward Taylor
 */
public class SATCacheQuery implements Callable<Solution> {

	private Database db;
	private String key;

	/**
	 * Creates a new SATCacheQuery that will search the {@link Database} for
	 * the given key.
	 * 
	 * @param db  - The Database to search
	 * @param key - The key for the SATProblem
	 * @see         SATCacheQuery
	 */
	public SATCacheQuery(Database db, String key) {

		this.db = db;
		this.key = key;
	}

	/**
	 * Searches in the {@link Database} for the given key from a 
	 * {@link SATProblem} and returns a {@link SATSolution} if it is found.
	 * 
	 * @return The SATSolution for the given SATProblem
	 * @throws Exception If the SQL query fails or there is no solution for the
	 *         problem in the database
	 * @see    SATCacheQuery
	 */
	@Override
	public Solution call() throws Exception {

		String sql = "SELECT * FROM `sat_cache` WHERE `problem_key` = ?";
		Connection c = db.getConnection();
		PreparedStatement ps = c.prepareStatement(sql);
		int numVars;
		byte[] data;
		try {
			ps.setString(1, key);
			ResultSet rs = ps.executeQuery();
			if (!rs.next()) {
				throw new SQLException("Problem key not in table");
			}
			numVars = rs.getInt("num_vars");
			data = rs.getBytes("solution");
		} finally {
			ps.close();
		}
		
		return new SATSolution(numVars, data);
	}
}